'use strict';

var redis = require('redis'),
  bluebird = require('bluebird'),
  debug = require('debug'),
  log = debug('yozh:lib:log'),
  error = debug('yozh:lib:error'),
  verbose = debug('yozh:lib:verbose');

// use node_redis with promises by promisifying node_redis with bluebird;
bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);

/**
 * a redis client
 * @param  {Object} redisOptions options
 * @return {Function} a redis client
 */
module.exports = exports = function redisCache(redisOptions) {
  var cache = {};
  // init redis client;
  var client = redis.createClient(
    redisOptions.port,
    redisOptions.host,
    redisOptions.options
  );

  // if (redisOptions.pwd) {
  //   client.auth(redisOptions.pwd, function() {
  //     log('redis auth success');
  //   });
  // }

  // if (redisOptions.dbId) {
  //   client.select(redisOptions.dbId, function(err) {
  //     if (err) {
  //       error('select db err, db num: ', dbId, err);
  //     }
  //   });
  // }

  client.on('ready', function(err) {
    log('ready: ', err);
  });

  client.on('error', function(err) {
    log('error: ', err);
  });

  client.on('connect', function(err) {
    log('connect: ', err);
    // set connect success state;
  });

  cache.client = client;
  cache.defaultCacheTime = redisOptions.defaultCacheTime;
  cache.defaultExpireTime = redisOptions.defaultExpireTime;

  /**
   * GET key
   * @param  {String} key key
   * @return {String} {key not exist: null,
   *                       key exist: old value, unknow key: err}
   */
  cache.get = function(key) {
    return cache.client.getAsync(key);
  };

  /**
   * SET key value [EX seconds] [PX milliseconds] [NX|XX]
   * EX second: expire second (SET key value EX second ==
   *   SETEX key second value)
   * PX millisecond: expire millisecond (SET key value PX millisecond ==
   *   PSETEX key millisecond value)
   * SET key value NX == SETNX key value,
   *   when key does not exist, set (key, value)
   * SET key value XX, when the key is exist, set (key, value)
   * @param {String} key   key
   * @param {String} value value
   * @return {String} {OK|NULL Bulk Reply}
   */
  cache.set = function(key, value) {
    return cache.client.setAsync(key, value);
  };

  /**
   * KEYS pattern: find all key with Regular Expressions
   * @param  {String} pattern Regular Expressions
   * @return {Array|Object|String} key list
   */
  cache.keys = function(pattern) {
    return cache.client.keysAsync(pattern);
  };

  /**
   * EXISTS key
   * @param  {String} key key
   * @return {Number} {1: true, 0: false}
   */
  cache.exists = function(key) {
    return cache.client.existsAsync(key);
  };

  /**
   * DEL key [key ...]
   * @param  {String} key key
   * @return {Number} number of deleted
   */
  cache.del = function(key) {
    return cache.client.delAsync(key);
  };

  /**
   * EXPIRE key seconds
   * @param  {String} key     key
   * @param  {Number} seconds seconds
   * @return {Number} {1: true, 0: false}
   */
  cache.expire = function(key, seconds) {
    return cache.client.expireAsync(key, seconds);
  };

  /**
   * EXPIREAT key timestamp
   * @param  {String} key       key
   * @param  {String} timestamp unix timestamp
   * @return {Number} {1: true, 0: false}
   */
  cache.expireat = function(key, timestamp) {
    return cache.client.expireatAsync(key, timestamp);
  };

  /**
   * RENAME key newkey
   * @param  {String} key    key
   * @param  {String} newkey newkey
   * @return {String} {OK|err}
   */
  cache.rename = function(key, newkey) {
    return cache.client.renameAsync(key, newkey);
  };

  /**
   * TTL key: time to live (second)
   * @param  {String} key key
   * @return {Number} {key not exsit: -2, no expire time: -1, Number: second}
   */
  cache.ttl = function(key) {
    return cache.client.ttlAsync(key);
  };

  /**
   * TYPE key
   * @param  {String} key key
   * @return {String} {none|string|list|set|zset|hash}
   */
  cache.type = function(key) {
    return cache.client.typeAsync(key);
  };

  return cache;
};
